package controllers
{
	import models.RESTResponse;
	
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.HTTPService;
	
	
	public class HTTPController
	{ 
		private static const BASE_URL:String = "http://127.0.0.1:8080/x";
		private static var _sid:String;
		private static var _wakeUpHandler:Function = null;
		
		public function HTTPController() {
		}
		
		public static function set sid(sid:String) : void {
			_sid = sid;
		}
		
		public static function set wakeUpHandler(callback:Function) : void {
			_wakeUpHandler = callback;
		}
		public static function get wakeUpHandler() : Function {
			return _wakeUpHandler;
		}
		
		public static function GET(url:String, params:XML = null, callback:Function = null) : void {
			send("GET", url, params, callback);
		}
		
		public static function POST(url:String, params:XML = null, callback:Function = null) : void {
			send("POST", url, params, callback);
		}
		
		public static function PUT(url:String, params:XML = null, callback:Function = null) : void {
			send("PUT", url, params, callback);
		}
		
		public static function DELETE(url:String, params:XML = null, callback:Function = null) : void {
			send("DELETE", url, params, callback);
		}
		
		private static function send(method:String, url:String, params:XML = null, callback:Function = null) : void {
			var service:HTTPService = new HTTPService();
			service.method			= "POST";
			service.url 			= BASE_URL + urlAddParameter(url, 'x:method', method)
			service.contentType		= "application/xml";
			service.resultFormat 	= "e4x";
			
			if(_sid != null) {
				service.url			= urlAddParameter(service.url, 'SESSIONID', _sid);
			}
			
			service.addEventListener(ResultEvent.RESULT, function (event:ResultEvent) : void {
				receive(event, callback);
			});
			service.send(params);
		}
		
		private static function receive(event:ResultEvent, callback:Function) : void {
			var xml:XML = dereferenceXMLById(event.result as XML);
			callback(new RESTResponse(xml));
		}
		
		private static function urlAddParameter(url:String, name:String, value:String) : String {
			if(url.indexOf('?') != -1) {
				url += '&' + name + '=' + value;
			} else {
				url += '?' + name + '=' + value;
			}
			return url;
		}
		
		/****** IMPORTANT *******
		 * Fonction de déréférencement de l'arbre XML.
		 * Compatible uniquement avec le mode REFERENCEID de Xstream.
		 */
		private static function dereferenceXMLById(src : XML) : XML {
			var dst:XML = src.copy();
			for(var i:int = 0, l:int = (src.descendants().(attribute('reference').length())).length(); i < l; i++) {
				var node:XML = (src.descendants().(attribute('reference').length()))[i];
				(dst.descendants().(attribute("id") == node.@id))[0] = (src.descendants()[node.name()].(attribute("id") == node.@reference))[0];
			}
			delete dst.descendants().@id;
			delete dst.@id;
			return dst;
		}
		
		public static function wait() : void {
			if(_sid != null) {
				GET('/comet/wait/?wait', null, function (response:RESTResponse) : void {
					HTTPController.wakeUpHandler(response);
					HTTPController.wait();
				});
			}
		}

	}
}